
#include <QPainter>

#include "ImageViewer.h"


namespace pi {

ImageViewer::ImageViewer(QWidget *parent) : QWidget(parent),
  imgW(0), imgH(0)
{
    m_muxData = new QMutex(QMutex::NonRecursive);

    m_img = NULL;

    connect(this, SIGNAL(call_signal()), this, SLOT(call_slot()));
}

ImageViewer::~ImageViewer()
{
    if( m_img != NULL ) {
        delete m_img;
        m_img = NULL;
    }

    delete m_muxData;
    m_muxData = NULL;
}

int ImageViewer::imshow(const std::string &name, cv::Mat &img)
{
    int     w, h, c;
    int     i, j;

    unsigned char *p1, *p2;

    m_name = name;

    // get mat image properties
    w = img.cols;
    h = img.rows;
    c = img.channels();
    p1 = img.data;

    // resize window
    if( imgW != w || imgH != h ) {
        imgW = w;
        imgH = h;
        call("resize");
    }


    // create background image
    m_muxData->lock();

    if( m_img != NULL ) delete m_img;
    m_img = new QImage(w, h, QImage::Format_RGB888);

    // copy pixel buffer
    if( c == 1 ) {
        for(j=0; j<h; j++) {
            p2 = m_img->scanLine(j);

            for(i=0; i<w; i++) {
                p2[i*3+0] = p1[i];
                p2[i*3+1] = p1[i];
                p2[i*3+2] = p1[i];
            }

            p1 += w;
        }
    } else {
        for(j=0; j<h; j++) {
            p2 = m_img->scanLine(j);

            for(i=0; i<w; i++) {
                p2[i*3+0] = p1[i*3+2];
                p2[i*3+1] = p1[i*3+1];
                p2[i*3+2] = p1[i*3+0];
            }

            p1 += w*3;
        }
    }

    m_muxData->unlock();

    // redraw
    call("update");

    return 0;
}

int ImageViewer::call(const std::string& cmd)
{
    callCmds.push(cmd);
    emit call_signal();
}


void ImageViewer::keyPressEvent(QKeyEvent *e)
{
//    // add key press event to queue
//    {
//        ru32        key_raw, key;
//        InputEvent  ev;

//        // convert Qt key code to universial key code
//        key_raw = e->key();
//        input_event_qt_code_trans(key_raw, key);

//        ev.type        = OSA_KEY_PRESS;
//        ev.code_raw    = key_raw;
//        ev.code        = key;
//        ev.timestamp   = tm_get_millis();

//        g_eventQueue->push(ev);
//    }
}


void ImageViewer::paintEvent(QPaintEvent *event)
{
    if( m_img != NULL ) {
        QPainter    painter(this);

        // draw image images
        m_muxData->lock();
        painter.drawImage(QPoint(0, 0), *m_img);
        m_muxData->unlock();
    }
}

void ImageViewer::closeEvent(QCloseEvent *event)
{

}

void ImageViewer::call_slot()
{
    if( callCmds.size() ) {
        std::string& cmd = callCmds.front();

        if( cmd == "update" ) this->update(this->rect());
        else if( cmd == "resize" ) this->resize(imgW, imgH);

        callCmds.pop();
    }
}



} // end of namespace pi
